//选做作业2
#include <stdio.h>
#include <malloc.h>
#include <string.h>

typedef struct{
	char id[10];
	char name[20];
	int math;
	int liner;
	int english;
	int sport;
}Student;

typedef struct Node{
	Student data;
	struct Node* next;
	
}LinkNode;


//创建单链表 读出学生记录
LinkNode* CreatList(const char*filename)
{
	FILE*file = fopen(filename,"r");
	if(!file) {
		printf("无法打开文件\n");
		exit(0);
	}
	LinkNode*head = (LinkNode*)malloc(sizeof(LinkNode));
	head->next = NULL;
	while(1)
	{
		Student student;
		if(fscanf(file,"%s %s %d %d %d %d",student.id,student.name,&student.math,&student.liner,&student.english,&student.sport)!=6)
		{
			break;
		}
		LinkNode*newNode = (LinkNode*)malloc(sizeof(LinkNode));
		newNode->next = head->next;
		newNode->data = student;
		head->next = newNode;
		
	}
	
	fclose(file);
	return head;
	
	
}

void Display(LinkNode *L)
{
	LinkNode* p = L->next;
	
	while(p!=NULL)
	{
		printf("学号：%-10s 姓名：%-8s 高数成绩：%-3d 线代成绩：%-3d 英语成绩：%-3d 体育成绩：%-3d\n",
			p->data.id,p->data.name,p->data.math,p->data.liner,p->data.english,p->data.sport);
		p = p->next;
	}
	
	
}


void sort(LinkNode*& L)
{
	//按照学生平均分排序
	
	//1.计算学生人数
	int len = 0;
	LinkNode* p = L->next;
	while(p!=NULL)
	{
		len++;
		p = p->next;
	}
	
	//2.排序
	p = L->next;
	for(int i = 0;i<len;i++)
	{
		p = L;
		LinkNode*cur = p->next;
		for(int j = 0;j<len-1;j++)
		{
			int sum1 = cur->data.math+cur->data.liner+cur->data.english+cur->data.sport;
			int sum2 = cur->next->data.math + cur->next->data.liner + cur->next->data.english + cur->next->data.sport;
			if(sum1<sum2&&cur->next->next!=NULL)
			{
				LinkNode *temp = cur->next;
				cur->next = cur->next->next;
				p->next = temp;
				p->next->next = cur;
				
				p = p->next;
				cur = cur->next;
			}
			else if(sum1<sum2&&cur->next->next==NULL)
			{
				LinkNode*temp = cur;
				p->next = p->next->next;
				temp->next=NULL;
				p->next->next = temp;
				
				p = p->next;
				cur = cur->next;
			}
		}
	
		
		
	}
}

void Insert(LinkNode*&L,Student newStudent)
{
	LinkNode*pre = L;
	LinkNode*p = L->next;
	int sumNew = newStudent.english + newStudent.sport + newStudent.math + newStudent.liner;
	while(p!=NULL)
	{
		int sum = p->data.english + p->data.liner + p->data.sport + p->data.math;
		if(sumNew>sum) break;
		
		pre = pre->next;
		p = p->next;
	}
	
	if(p!=NULL)
	{
		LinkNode* s = (LinkNode*)malloc(sizeof(LinkNode));
		s->data = newStudent;
		s->next = pre->next;
		pre->next = s;
	}
	else if(p==NULL)
	{
		LinkNode* s = (LinkNode*)malloc(sizeof(LinkNode));
		s->next = NULL;
		s->data = newStudent;
		pre->next = s;
	}
}
void ModifyScore(LinkNode*&L,const char *id,const char*subject,int score)
{
	LinkNode*p = L->next;
	while(p!=NULL)
	{
		if(strcmp(p->data.id,id)==0)
		{
			if(strcmp(subject,"math")==0) p->data.math=score;
			else if(strcmp(subject,"liner")==0) p->data.liner=score;
			else if(strcmp(subject,"english")==0) p->data.english=score;
			else if(strcmp(subject,"sport")==0) p->data.sport=score;
			break;
		}
		p = p->next;
	}
	sort(L);//重新排序
}


void DestoryList(LinkNode* &L)
{
	if(L->next==NULL) return;
	LinkNode*pre = L;
	LinkNode*p = L->next;
	
	while(p!=NULL)
	{
		free(pre);
		pre = p;
		p = p->next;
	}
	free(pre);
	pre=NULL;
	
}

void SaveToFile(LinkNode*L,const char*filename)
{
	
	FILE*file = fopen(filename,"w");
	if(!file)
	{
		printf("无法打开文件\n");
		exit(0);
	}
	LinkNode*p = L->next;
	while(p!=NULL)
	{
		fprintf(file,"%s %s %d %d %d %d\n",p->data.id,p->data.name,p->data.math,p->data.liner,p->data.english,p->data.sport);
		p = p->next;
	}
	
	fclose(file);
}




int main()
{
	LinkNode*L = CreatList("student.txt");
	printf("(1)存入完毕\n");
	printf("(2)显示信息如下：\n");
	Display(L);
	
	printf("(3)按照平均分降序排序之后：\n");
	sort(L);
	Display(L);
	
	printf("(4)插入学生记录，并能使记录还按平均分降序排序：\n");
	Student new_student = {"22012718","xiaoming",85,95,65,75};
	Insert(L,new_student);
	Display(L);
	printf("又插入一个：\n");
	Student new_student1 = {"21012718","xiao",120,100,100,100};
	Insert(L,new_student1);
	Display(L);
	
	
	printf("(5)修改某个学生某门课的分数，并能使记录还按平均分降序排序:\n");
	ModifyScore(L,"21012718","math",77);
	Display(L);
	
	
	printf("(6)将单链表L中的所有记录存回到student.txt文件中\n");
	SaveToFile(L,"student.txt");
	
	//销毁链表
	DestoryList(L);
	return 0;
}
